package com.example.demo.controller;

import com.example.demo.util.ZookeeperLockUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.locks.InterProcessSemaphoreMutex;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * 测试基于zookeeper的分布式锁，基于curator
 */
@RestController
@Slf4j
public class ZookeeperController {

    //@Autowired
    private CuratorFramework curatorFramework;

    private String lockPath = "/test/lock";
    /**
     * 通过zookeeper分布式锁高并发测试
     * @author lst
     * @date 2020-6-4 14:53
     * @return com.example.mybatiesplus.result.BaseResponse
     */
    @GetMapping(value = "/zkTest", produces = "application/json; charset=utf-8")
    public String zkTest() {
        //String lockName = lockPath + UUID.randomUUID().toString();
        String lockName = lockPath;
        log.info("============={} 线程访问开始=========lockName:{}",Thread.currentThread().getName(),lockName);
        /**
         * curator 的几种锁方案 ：
         * 1、InterProcessMutex：分布式可重入排它锁
         * 2、InterProcessSemaphoreMutex：分布式排它锁
         * 3、InterProcessReadWriteLock：分布式读写锁
         */
        // 获取分布式锁
        InterProcessSemaphoreMutex lock = new InterProcessSemaphoreMutex (curatorFramework, lockName);
        try{
            //获取锁资源
            boolean flag = lock.acquire(10, TimeUnit.HOURS);
            //System.out.println("当前需要获取锁的所有节点 ：" + lock.);
            if(flag){
                log.info("线程:{}，获取到了锁",Thread.currentThread().getName());
                //TODO 获得锁之后可以进行相应的处理  睡一会
                Thread.sleep(5000);
                log.info("======获得锁后进行相应的操作======" + Thread.currentThread().getName());
            }
        }catch (Exception e){
            log.info("错误信息：{}",e.getMessage());
        }finally {
            try {
                lock.release();
                log.info("=========lockName:{}==============={}释放了锁",lockName,Thread.currentThread().getName());
            } catch (Exception e) {
                log.info("错误信息：{}",e.getMessage());
            }
        }
        return "调用分布式锁成功!";
    }

    @GetMapping(value = "/zkTest2", produces = "application/json; charset=utf-8")
    public String zkTest2() {
        ZookeeperLockUtil.getZookeeperLock(curatorFramework, lockPath);
        return "调用分布式锁2成功!";
    }
}
